const BaseService = require('./BaseService');
const tradeDao = require('../dao/TradeDao');
const DateUtil = require('../utils/DateUtil');
const depositRate = Number(process.env.depositRate) || 0.05;

/**
 * Market Service
 */
class MarketService extends BaseService {
  /**
   * get market info
   * @param {CoinType} baseCoinType
   * @param {CoinType} counterCoinType
   * @param {Boolean} more
   * @return {Object<marketInfo>}
   */
  async getMarketInfo(baseCoinType, counterCoinType, more) {
    const info = new Object();
    const promises = new Array();

    promises.push(
      tradeDao.countTradeVolume(baseCoinType, counterCoinType, DateUtil.getDatePre24H())
    );
    promises.push(tradeDao.getLastPriceTo(baseCoinType, counterCoinType));
    promises.push(tradeDao.getFirstPriceFrom(baseCoinType, counterCoinType, DateUtil.today()));

    if (more) {
      promises.push(tradeDao.countTradeVolume(baseCoinType, counterCoinType, DateUtil.today()));
      promises.push(tradeDao.countTradeAmount(baseCoinType, counterCoinType, DateUtil.today()));
      promises.push(tradeDao.getTopPrice(baseCoinType, counterCoinType, DateUtil.today()));
      promises.push(tradeDao.getBottomPrice(baseCoinType, counterCoinType, DateUtil.today()));
      promises.push(tradeDao.getLastPriceTo(baseCoinType, counterCoinType, DateUtil.today()));
    }

    const [
      tradeVolumeIn24H,
      recentPrice,
      firstPriceToday,
      tradeVolumeToday,
      tradeAmountToday,
      topPriceToday,
      bottomPriceToday,
      lastPriceYesterday,
    ] = await Promise.all(promises);

    const priceDiffAmount = recentPrice - firstPriceToday;
    const priceDiffPercent = Number(
      ((!recentPrice ? 0 : priceDiffAmount / recentPrice) * 100).toFixed(2)
    );

    Object.assign(info, {
      depositRate,
      tradeVolumeIn24H,
      recentPrice,
      priceDiffAmount,
      priceDiffPercent,
    });

    if (more) {
      Object.assign(info, {
        tradeVolumeToday,
        tradeAmountToday,
        topPriceToday,
        bottomPriceToday,
        firstPriceToday,
        lastPriceYesterday,
      });
    }

    return info;
  }

  /**
   * getMarketPriceBetween
   * @param {CoinType} baseCoinType
   * @param {CoinType} counterCoinType
   * @param {Date} from
   * @param {Date} to
   * @return {Promise}
   */
  async getMarketPriceBetween(baseCoinType, counterCoinType, from, to) {
    const promises = new Array();

    promises.push(tradeDao.getLastPriceBetween(baseCoinType, counterCoinType, from, to));
    promises.push(tradeDao.countTradeVolume(baseCoinType, counterCoinType, from, to));

    const [Price, Volume] = await Promise.all(promises);

    return { Price, Volume };
  }

  /**
   * getKLineBetween
   * @param {CoinType} baseCoinType
   * @param {CoinType} counterCoinType
   * @param {Date} from
   * @param {Date} to
   * @return {Promise}
   */
  async getKLineBetween(baseCoinType, counterCoinType, from, to) {
    const promises = new Array();

    promises.push(tradeDao.getFirstPriceBetween(baseCoinType, counterCoinType, from, to));
    promises.push(tradeDao.getLastPriceBetween(baseCoinType, counterCoinType, from, to));
    promises.push(tradeDao.getTopPrice(baseCoinType, counterCoinType, from, to));
    promises.push(tradeDao.getBottomPrice(baseCoinType, counterCoinType, from, to));
    promises.push(tradeDao.countTradeVolume(baseCoinType, counterCoinType, from, to));

    const [Open, Close, High, Low, Volume] = await Promise.all(promises);

    return { Open, Close, High, Low, Volume };
  }
}

module.exports = new MarketService();
